//
//  XMLUtil.swift
//  maozzi-rss
//
//  Created by 帽子 on 2020/5/30.
//  Copyright © 2020 帽子. All rights reserved.
//	XML 工具

import SwiftUI

final class RSSUtil {
    static func get() -> [NewsItem] {
        let userDatasources = (UserDefaults.standard.array(forKey: "userDatasources") ?? []) as [String]
        var xmlData: [NewsItem] = []
        let decoder = JSONDecoder()
        for item in userDatasources {
            let dataSourceItem = try? decoder.decode(DatasourceItem.self, from: item.data(using: .utf8)!)
            if dataSourceItem != nil {
                xmlData += XmlParser(item: dataSourceItem!).xmlData
            }
        }
        // 去除已读
        let dict: [NewsItem] = LocalCacheUtil.getAll(filename: UserData.readCacheFileName)
        for item in xmlData {
            if dict.contains(item) {
                xmlData.remove(at: xmlData.firstIndex(of: item)!)
            }
        }
        return xmlData
    }
}

private class XmlParser: NSObject, XMLParserDelegate {
    var xmlData: [NewsItem] = []
    // 当前元素名
    var currentElement = ""
    var newsItem: NewsItem!
    var dateFormat: String?
    var logo: String?
    

    init(item: DatasourceItem) {
        super.init()
        dateFormat = item.dateFormat
        logo = item.logo
        let parser = XMLParser(contentsOf: URL(string: item.rss_url)!)!
        parser.delegate = self
        parser.parse()
    }

    // 解析到起始标签
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String] = [:]) {
        currentElement = elementName
        if elementName == "item" {
            newsItem = NewsItem()
            newsItem.logo = logo
            newsItem.dateFormat = dateFormat
        }
    }

    // 遇到字符串时调用
    func parser(_ parser: XMLParser, foundCharacters string: String) {
        let data = string.trimmingCharacters(in: .whitespacesAndNewlines)
        if newsItem == nil {
            return
        }
        // 接下来每遇到一个字符，将该字符追加到相应的 property 中
        switch currentElement {
        case "title":
            newsItem.title = (newsItem.title ?? "") + data.pregReplace(pattern: " ", with: "")
        case "link":
            newsItem.id = (newsItem.id ?? "") + data
            newsItem.link = (newsItem.link ?? "") + data
        case "description":
            newsItem.description = (newsItem.description ?? "") + data
            newsItem.content = (newsItem.content ?? "") + data.pregReplace(pattern: "<[^>]*>", with: "")
                .pregReplace(pattern: "&nbsp;", with: "")
                .pregReplace(pattern: "&quot;", with: "")
                .pregReplace(pattern: " ", with: "")
        case "pubDate":
            newsItem.pubDate = (newsItem.pubDate ?? "") + data
        default:
            break
        }
    }

    // 遇到结束标签时调用
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        // 标签User结束时将该用户对象，存入数组容器。
        if elementName == "item" {
            xmlData.append(newsItem)
        }
    }
}

extension String {
    // 1 返回字数
    var count: Int {
        let string_NS = self as NSString
        return string_NS.length
    }

    // 使用正则表达式替换
    func pregReplace(pattern: String, with: String, options: NSRegularExpression.Options = []) -> String {
        let regex = try! NSRegularExpression(pattern: pattern, options: options)
        return regex.stringByReplacingMatches(in: self, options: [], range: NSMakeRange(0, count), withTemplate: with)
    }
}
